<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2009 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: liu21st <liu21st@gmail.com>
// +----------------------------------------------------------------------
namespace kyd\kyd_extend\crypt;

use kyd\kyd_extend\string\string;

/**
 * Crypt 加密实现类
 */

class BaseCrypt {

    public $config = [];

    public $key = '';

    public $strLen = 0;

    public $data = '';

    public $rsa = '';

    public $string = '';


    public function __construct($config){
        $this->config = $config;
        $this->key = isset($config['key'])?$config['key']:'';
        $this->rsa = new Rsa($this->config);
        $this->string = new String();
    }



    /**
     * @dec 解密
     * S string 字符串
     * I index 开始下标
     * T type  类型 1-增加 2-删除 3-修改 4-查询
     * @param $str
     * @param $sign
     * @throws \Exception
     */

    public function getDecrypt($str,$sign){

//        var_dump($str);
//        var_dump($sign);
//        die();

//        $this->data = $str = 'rA';
//        $sign = "bBVHyChgHZZDImSpPb4ycz48MJCgMMK2q9v970cf7bE/v27pAia3IVhZANn4GxSOiFJJ4rYx80NpaOU44tDPSRdO2onNIBBsAfv1TxZdT3/lGtwNSp2tUgOujc0NArrJH1Q6pN1ZzSenb6TkhBqgp4ul+vL2dLnVFxD2dnJInydxfaXOc1/IkswR4AcicIquVQobfUnnWQguePrpx/fBrBVx0OJQSYNvtF7/c8e9CwWaRJStXqPqrZDCU3zwJTjd1w8WJ1YS9qtE7qvzykfGgHUPc+/EkmkYgtoSIcRsuOhAGMcHLZ+gqbQvWR+kwE+aKXF0tiNcY1e5iBhKJS+h6g==";


        $this->data = $str;
        $signData =  $this->rsa->privateDecrypt($sign);

        if (!is_array($signData)){
            return $this->errCode(RsaCodeEnum::$DATAANALYSIS);
        }

        echo '<br>';

        echo '解'.'<br>';


        var_dump($this->data);
        echo '<br>';
        var_dump(json_encode($signData['data']));
        echo '<br>';

//        die();

        $this->strLen = mb_strlen($this->data);


        $resultArr = [];

        foreach ($signData['data'] as $key => $val){

            if ($val['T'] == 1){

                $len = mb_strlen($val['S']);

                $start = mb_substr($this->data,0,$val['I']);

                $end = mb_substr($this->data,$val['I'] + $len);

                array_unshift($resultArr,$start . $end);

            }

            else if ($val['T'] == 2){ //删除

                $start = mb_substr($this->data,0,$val['I']);

                $end = mb_substr($this->data,$val['I']);

                array_unshift($resultArr,$start.$val['S'].$end);


            }else if($val['T'] == 3){ //修改

                $len = mb_strlen($val['S']);

                $start = mb_substr($this->data,0,$val['I']);

                $end = mb_substr($this->data,$val['I'] + $len);

                array_unshift($resultArr,$start.$val['S'].$end);

            }else{
                array_unshift($resultArr,$val['S']);
            }

        }


        echo '连接'.'<br>';

        var_dump($resultArr);

        $data =  Crypt::decrypt($this->data,$this->key);

        echo '<br>';
        var_dump($data);
//        die();

        return $data;

    }


    //加密
    public function setEncrypt($data){

        //外壳加密
        $this->data =  Crypt::encrypt($data,$this->key);
        var_dump($this->data);
        echo '<br>';
//        die();
        $this->strLen = mb_strlen( $this->data);

        if ($this->strLen < 2){
           return $this->errCode(RsaCodeEnum::$DATAANALYSIS);
        }

        //动态密码
        $number = $this->getDoWhile($this->strLen); //外层分段


        $pageSize = ceil($this->strLen / $number );

        $this->data = str_split($this->data, $pageSize);

        var_dump($this->data);
        echo '<br>';

        $arr = [];

        foreach ($this->data as $key => $val){

            var_dump($key);
            echo '<br>';

            $type = $this->string->randString(1,8); //获取类型

            var_dump($type);

            echo 'type'.'<br>';

            $valLen = mb_strlen($val);

            if ($type == 1){  //增加
                $strNum = $this->string->randString(1,7); //外层分段
                var_dump($strNum);
                echo '<br>';
                $token = $this->string->randString($strNum,6); //获取随机字符串
                var_dump($strNum);
                echo '<br>';
                $D = $val.$token;
            }

            else if ($type==2){ //删除

                if ($valLen < 2 ){
                    continue;
                }

                $strNum = $this->getDoWhile($valLen); //外层分段

                if ($valLen >= $strNum){

                    $startTemp = mb_substr($val,0,$valLen - $strNum);
                    var_dump($startTemp);
                    echo '<br>';
                    $token = mb_substr($val,$valLen - $strNum);
                    var_dump($token);
                    echo '<br>';
                    $D = $startTemp.$token;

                }else{
                    $token = $val;
                    $D = $val;
                }

            }

            else if ($type == 3){  //修改

                if ($valLen < 2) continue;

                $strNum = $this->getDoWhile($valLen); //外层分段

                $token = $this->string->randString($strNum,6); //获取随机字符串

                $startTemp = mb_substr($val,0,$valLen - $strNum);

                $realyToken = mb_substr($val,$valLen - $strNum);

                $D = $startTemp.$token;

                $token = $realyToken;

            }else{
                $token = $val;
                $D = $val;
            }

            $flg=[
                'S'=>$token,
                'N'=>$key,
                'T'=>$type,
                'D'=>$D,
            ];

            array_unshift($arr,$flg);
        }

        $result = '';

        foreach ($arr as &$value){
            $result.= $value['D'];
            $value['I'] = mb_strlen($result);
        }

        var_dump(json_encode($arr));
        echo '<br>';
        var_dump($result);
//        die();

       return ['sign'=>$this->rsa->publicEncrypt($arr),'data'=>$result];

    }

    public function getDoWhile($valLen){

        $num = 0;

        do {

            if ($num>=3){
               return ceil($valLen / 2);
            }

            $strNum = $this->string->randString(1,7); //外层分段
            $num +=1;

        } while ( $strNum >= $valLen);

        return $strNum;
    }


    public function errCode($code){
        return ['code'=>$code,'message'=>RsaCodeEnum::$OBJECT[$code],'data'=>[]];
    }


}
